<?php
/**
 * 集合場所関連ページコントローラモジュール
 */
require_once 'Request/Request.php';
require_once 'Session.php';
require_once 'Form/OnlyHiddenAction.php';
require_once APPLICATION_PATH . '/views/Components/YMap/YMapCtrl.php';
require_once APPLICATION_PATH . '/views/Components/YMap/YMap.php';
require_once APPLICATION_PATH . '/models/Names/Names.php';
require_once APPLICATION_PATH . '/models/Place/Controller.php';
require_once APPLICATION_PATH . '/views/Components/MapSelect/MapSelectPartial.php';
require_once dirname(__FILE__) . '/StaffController.php';

class PlaceController extends Zend_Controller_Action
{
	/** 値：自ＵＲＬ：新規登録 */
	const VALUE_SELFURL_ADD ='/Place/add/';
	/** エラーメッセージ：集合場所の名前が登録済み */
	const ERRMSG_DUPLICATION_PLACENAME = '集合場所の名前が登録済みです。';
	/** 完了メッセージ：登録 */
	const COMPMSG = '集合場所を登録しました。';
	/** エラーメッセージ：アンロック検出 */
	const ERRMSG_UNLOCK_PLACEMENU = '別画面から会場メニューの変更を検出しました。最初からやり直してください。';
	/** エラーメッセージ：削除済み */
	const ERRMSG_DELETED_ALREADY = "この会場はすでに削除済みです。";

	/** HTTPリクエストオブジェクト */
	protected $_objHttpRequest;
	/** YMAP制御オブジェクト */
	protected $_objYmapCtrl;
	/** YMAP描画オブジェクト */
	protected $_objYmap;
	/** セッションオブジェクト */
	protected $_objSession;

	public function init()
	{
		$this->_objHttpRequest = new Lib_Request();
		$sessionKey = get_class();
		$this->_objSession = new Lib_Session($sessionKey);
	}
	/**
	 * 集合場所追加画面
	 * /application/views/scripts/place/add.tpl
	 */
	public function addAction()
	{
		/*** スタッフログイン判定 */
		$uid = $this->_areYouStaff();
		/** 遷移元ＨＴＴＰリクエストが設定されていれば、これをセッションに保存する */
		if ($this->_objHttpRequest->get('done') != '') {
			$this->_objSession->setValue('done', $this->_objHttpRequest->get('done'));
		} else {
			$this->_redirect('/errror');
			exit();
		}
		/***
		 * AssemblyYMapLinkのパラメータが設定されている場合
		 * そのなかから緯度経度を取得する
		 * 集合場所登録画面からのキャンセルを想定
		 */
		$Lat = '';
		$Lon = '';
		$AssemblyYMapLink = $this->_objHttpRequest->get(Names::ASSEMBLYYMAPLINK);
		$this->_explodeAssemblyYMapLink($Lat, $Lon, $AssemblyYMapLink);

		/**
		 * 管理画面から変更リクエストが渡された場合
		 * 画面にそのまま渡す
		 */
		$this->view->CHANGE_REQUEST = $this->_objHttpRequest->get(Names::CHANGE_COORDINATE);

		/***
		 * Y!地図描画オブジェクト
		 */
		$this->_objYmap = new Components_Ymap_Controller('place', $Lat, $Lon);
		$this->view->YMAP = $this->_objYmap->fetch(	);

		/***
		 * Y!地図座標インターフェイスコントロールオブジェクト
		 */
		$this->view->FORM_NAME = Names::FORMASSEMBLYPLACE;
		$this->_objYmapCtrl = new Components_YMapCtrl('place', $this->view->FORM_NAME);
		$this->view->YMAPCTRL = $this->_objYmapCtrl->fetch();
	}

	/**
	 * 会場Ｙ！マップＵＲＬのなかから緯度経度を取得する
	 * @param unknown $Lat
	 * @param unknown $Lon
	 * @param unknown $AssemblyYMapLink
	 */
	protected function _explodeAssemblyYMapLink(&$Lat, &$Lon, $AssemblyYMapLink)
	{
		$Lat = '';
		$Lon = '';
		if ($AssemblyYMapLink == '') {
			return;
		}
		$aryParsedUrl = parse_url($AssemblyYMapLink);
		if ($aryParsedUrl === FALSE) {
			return;
		}
		$sQuerys = $aryParsedUrl["query"];
		$aryQuerys = array();
		parse_str($sQuerys, $aryQuerys);
		/*** 緯度設置判定 */
		if (isset($aryQuerys['lat'])){
			$Lat = $aryQuerys['lat'];
			/*** 経度設置判定 */
			if (isset($aryQuerys['lon'])){
				$Lon = $aryQuerys['lon'];
			} else {
				$Lat = '';
			}
		}
	}

	/**
	 * 登録YMAP確認画面
	 * application/views/scripts/place/checkview.tpl
	 */
	public function checkviewAction()
	{
		$Lat = $this->_objHttpRequest->get('lat');
		$Lon = $this->_objHttpRequest->get('lon');
		$this->view->placeName =$this->_objHttpRequest->get('name');
		/***
		 * Y!地図描画オブジェクト
		*/
		$this->_objYmap = new Components_Ymap_Controller('checkview', $Lat, $Lon);
		$this->view->htmlYMap = $this->_objYmap->fetch();
	}

	/**
	 * 集合場所削除
	 */
	public function deleteAction()
	{
		/*** スタッフログイン判定 */
		$uid = $this->_areYouStaff();
		/** シーケンスＩＤが設定されていない場合は、エラーページに遷移する。 */
		if  ($this->_objHttpRequest->get(Models_Place_Xml_Controller::KEY_ID) == '') {
			$this->redirect('/error');
			exit;
		}

		$objPlace = new Models_Place_Xml_Controller();
		$ret = $objPlace->delete($this->_objHttpRequest->get(Models_Place_Xml_Controller::KEY_ID));
		if ($ret !== FALSE) {
			$objPlace->saveToFile();
			/***
			 * 遷移元に戻る
			*/
			$this->_jumpToBack();
			exit();
		}
		$this->view->URL_BACK = $this->_makeBackUrl();
		$this->view->ERR_MSG = self::ERRMSG_DELETED_ALREADY;
	}

	/**
	 * スタッフとしてログイン済みかチェックする
	 * ログインしていない場合は、ログイン画面に遷移する
	 * ログインしている場合はUIDを返す
	 */
	protected  function _areYouStaff()
	{
		/*** ログインIDを取得する */
		$uid = StaffController::getLoginId();
		/*** ログインIDが取得できない（未ログイン）の場合、ログイン画面に遷移する */
		if ($uid == '') {
			$this->_redirect('/Staff/login');
			exit();
		}
		return $uid;
	}

	/**
	 * 集合場所登録
	 * /application/views/scripts/place/regist.tpl
	 * 登録確認メッセージを表示するだけの空ブラウザ画面
	 */
	public function registAction()
	{
		/*** スタッフログイン判定 */
		$uid = $this->_areYouStaff();
		/*** 戻るボタンが押された場合、戻る */
		if ($this->_objHttpRequest->get(Names::BACK) == Names::NAME_BUTTON_BACK) {
			$this->_jumpToBack();
			exit();
		}
		$this->view->ERR_MSG = '';
		$this->view->COMP_MSG = '';
		/***
		 * 集合場所名が重複している場合、警告を表示し追加画面に戻る
		 * 戻り先ＵＲＬは、form action に記載
		 * ただしシーケンスＩＤがリクエストに設定されている場合は、変更を目的としているため
		 * 重複を許可する
		 */
		$newmname = $this->_objHttpRequest->get(Names::ASSEMBLYPLACE);
		$ymapurl = $this->_objHttpRequest->get(Names::ASSEMBLYYMAPLINK);
		$this->view->NEWMNAME = $newmname;
		$this->view->YMAPURL = $ymapurl;
		/*** 会場場所データクラスインスタンス作成 */
		$objPlace = new Models_Place_Xml_Controller();
		$Dataset = $objPlace->searchKey(Models_Place_Xml_Controller::KEY_NAME, $newmname);
		/*** 新規登録（シーケンスIDがリクエストに設定されていない）場合は、会場名重複チェックを実施 */
		if  ($this->_objHttpRequest->get(Models_Place_Xml_Controller::KEY_ID) == '') {
			if ($Dataset !== FALSE)  {
				$this->view->ERR_MSG = self::ERRMSG_DUPLICATION_PLACENAME;
				return;
			}
		}
		/*** 重複判定ＥＮＤ */

		/***
		 * 集合場所登録
		 */
		$id = $this->_objHttpRequest->get(Models_Place_Xml_Controller::KEY_ID);
		$objPlace->putData($newmname, $ymapurl, $id);
		$objPlace->saveToFile();

		/***
		 * 遷移元に戻る
		 */
		$this->_jumpToBack();
	}

	/**
	 * 会場メニュー並び替え画面
	 * /application/views/scripts/place/permute.tpl
	 */
	public function permuteAction()
	{
		/*** スタッフログイン判定 */
		$uid = $this->_areYouStaff();
		/*** リファラーパラメータ必須チェック */
		if (!isset($_REQUEST[Names::REFERER])) {
			if ($this->_objSession->getValue(Names::REFERER) != '') {
				$_REQUEST[Names::REFERER] = $this->_objSession->getValue(Names::REFERER);
			} else {
				$_REQUEST[Names::ERROR_TITLE] = "集合場所並び替え画面リクエストエラー";
				$param = Names::ERROR_TITLE . '=' . "集合場所並び替え画面リクエストエラー";
				$this->_redirect('/Error/error?' . $param);
				exit;
			}
		} else {
			$this->_objSession->setValue(Names::REFERER, $_REQUEST[Names::REFERER]);
		}
		/*** 会場データ読み込み */
		$objMap = new Models_Place_Xml_Controller();
		$this->_MapDataset = $objMap->getArrayData();
		/*** 会場データをテンプレートに通知 */
		if (is_array($this->_MapDataset)){
			$this->view->MapDataset = $this->_MapDataset['LIST'];
		} else {
			$this->view->MapDataset = array();
		}
		/*** キャンセルフォームオブジェクトをテンプレートに通知 */
		$this->view->objCancelForm = $this->_createPermuteCancelForm();
		/*** 並び替え登録画面アクションＵＲＬをテンプレートに通知 */
		$this->view->urlRegistAction
		= '/Place/permuteregist?' . Names::REFERER .'=' . $_REQUEST[Names::REFERER];
	}

	/**
	 * 会場一覧画面
	 * 名称変更（別画面）、座標変更（別画面）
	 * /application/views/scripts/place/edit.tpl
	 *
	 */
	public function listAction()
	{
		/*** ログインIDを取得する */
		$uid = StaffController::getLoginId();
		/*** ログインIDが取得できない（未ログイン）の場合ログイン画面に遷移する */
		if ($uid == '') {
			$this->_redirect('/Staff/login');
			exit();
		}
		/*** 会場データ読み込み */
		$objMap = new Models_Place_Xml_Controller();
		$aryMap = $objMap->getArrayData();
		$this->view->MapDataset = $aryMap['LIST'];
		if (!is_array($this->view->MapDataset)) {
			$this->view->MapDataset = array();
		}
	}

	/** 編集フラグ */
	const VALUE_EDIT_FLG = '1';
	/**
	 * 会場編集画面
	 * 名称変更・座標変更
	 * HTTPリクエストに
	 * AssemblyPlace（会場名）、AssemblyYMapLink（編集対象Y! 地図URL）、ＩＤ（会場のユニークＩＤ）が設定されていること
	 */
	public function editAction()
	{
		/** 遷移元ＨＴＴＰリクエストが設定されていれば、これをセッションに保存する */
		if ($this->_objHttpRequest->get('done') != '') {
			$this->_objSession->setValue('done', $this->_objHttpRequest->get('done'));
		} else {
//			$this->_redirect('/errror');
//			exit();
		}
		/***
		 * ＩＤが未設定の場合、エラー画面に遷移する
		 */
		if ($this->_objHttpRequest->get(Models_Place_Xml_Controller::KEY_ID) == '') {
			$this->_redirect('/error');
			exit();
		}
		$this->view->ID = $this->_objHttpRequest->get(Models_Place_Xml_Controller::KEY_ID);
		/***
		 * AssemblyYMapLinkのパラメータが設定されている場合
		* そのなかから緯度経度を取得する
		* 集合場所登録画面からのキャンセルを想定
		*/
		$Lat = '';
		$Lon = '';
		$AssemblyYMapLink = $this->_objHttpRequest->get(Names::ASSEMBLYYMAPLINK);
		$this->_explodeAssemblyYMapLink($Lat, $Lon, $AssemblyYMapLink);

		/***
		 * Y!地図描画オブジェクト
		*/
		$this->_objYmap = new Components_Ymap_Controller('place', $Lat, $Lon);
		$this->view->YMAP = $this->_objYmap->fetch(	);

		/***
		 * Y!地図座標インターフェイスコントロールオブジェクト
		*/
		$this->view->FORM_NAME = Names::FORMASSEMBLYPLACE;
		$this->_objYmapCtrl = new Components_YMapCtrl('place', $this->view->FORM_NAME);
		$this->view->YMAPCTRL = $this->_objYmapCtrl->fetch(self::VALUE_EDIT_FLG);

	}

	/**
	 * リファラーが設置されたリクエストを取得する
	 * @return string
	 */
	protected function _getHttpRequestReferer()
	{
		$sResult = '';
		$sResult = $this->_objHttpRequest->get(Names::REFERER);
		/*** 未設定の場合は、トップ画面をリファラーとして返却 */
		if ($sResult == '') {
			$sResult = '/';
		}
		return $sResult;
	}

	/*** 会場メニュー並び替え画面キャンセルフォーム：ネーム属性値 */
	const PERMUTE_CANCEL_FORM_NAME = 'permute_canel_form';
	/*** 会場メニュー並び替え画面キャンセルフォーム：クラス属性値 */
	const PERMUTE_CANCEL_FORM_CLASS_NAME = '会場メニュー並び替え画面キャンセルフォーム';
	/**
	 * キャンセルフォーム：会場メニュー並び替え画面用
	 * @return string
	 */
	protected function _createPermuteCancelForm()
	{
		/*** ACTIONをリファラーが設置されたリクエストを取得する */
		$action = $this->_getHttpRequestReferer();
		/*** NAME属性値を定数から設置 */
		$name = self::PERMUTE_CANCEL_FORM_NAME;
		/*** CLASS属性値を定数から設置 */
		$className = self::PERMUTE_CANCEL_FORM_CLASS_NAME;
		/*** キャンセルフォームインスタンス生成 */
		$objCancelForm = new Hlib_Form_OnlyHiddenAction($name, $action);
		/*** クラス属性通知 */
		$objCancelForm->GeneralAttibutes->class = $className;
		/*** リターン */
		return $objCancelForm;
	}

	/**
	 * 並び替え登録
	 * 正常画面なし（呼び出し元に戻る）
	 * ロック不一致等のメッセージ画面
	 * /application/views/scripts/place/permuteregist.tpl
	 */
	public function permuteregistAction()
	{
		/*** 変更内容保存 */
		$this->registPermuteRegist();
		/*** 画面作成 */
		$this->displayPermuteRegist();
	}

	/**
	 * 並び替え登録完了画面
	 * 変 更 内 容 登 録 部
	 */
	protected function registPermuteRegist()
	{
		/*** 並べ替えＩＤ */
		$permutedIdList = explode(',', $this->_objHttpRequest->get('result'));
		/*** 会場データ読み込み */
		$objMap = new Models_Place_Xml_Controller();
		$MapDataset = $objMap->getArrayData();
		/*** 登録会場数算出 */
		$countMapDataset = count($MapDataset["LIST"]);

		/***
		 * 並べ替えＩＤのかずと、メニューの数が一致しない場合
		* 別のプロセスによりメニューに変更が加えられたと判定
		* 処理を中止する。
		*/
		//*stab*/$countMapDataset = 99;
		if ($countMapDataset != count($permutedIdList)) {
			$this->view->messageError = self::ERRMSG_UNLOCK_PLACEMENU;
			return;
		}

		$i = 0;

		/*** 並び順が変更がない場合何もしない */
		while ($i < $countMapDataset) {
			if ($MapDataset["LIST"][$i][Models_Place_Xml_Controller::KEY_ID]  != $permutedIdList[$i]) {
				break;
			}
			$i ++;
		}
		/*** 並び順に変更があった */
		if ($i != $countMapDataset) {
			$permutedPlaceList = array();
			/*** 会場情報を新しい並びでバッファリングする */
			foreach ($permutedIdList as $permutedId) {
				$MapData = $objMap->searchKey(Models_Place_Xml_Controller::KEY_ID, $permutedId);

				/*** 該当ＩＤのメニューが見つからなかった場合はメッセージ画面 */
				if ($MapData === FALSE) {
					$this->view->messageError = self::ERRMSG_UNLOCK_PLACEMENU;
					return;
				}

				/*** 会場情報をバッファリング */
				$permutedPlaceList[] = $MapData;
			}
			/*** バッファリングが完了したら会場情報クラスを初期化する */
			$objMap->clear();
			/*** 初期化した会場情報クラスに新しい並びでバッファリングした情報を設置 */
			foreach ($permutedPlaceList as $permutedPlace) {
				$objMap->putData(
						$permutedPlace[Models_Place_Xml_Controller::KEY_NAME],
						$permutedPlace[Models_Place_Xml_Controller::KEY_MAPURL],
						$permutedPlace[Models_Place_Xml_Controller::KEY_ID]);
			}
			/*** 新たな並びの会場情報を保存する */
			$objMap->saveToFile();
		}
	}

	/**
	 * 並び替え登録完了画面
	 * 画 面 部
	 */
	protected function displayPermuteRegist()
	{
		/*** 集合場所選択メニュー */
		$objAssenbly = new Components_MapSelect_Partial();
		$this->view->PlaceMenu = $objAssenbly->fetchPulldownMenu();
		/*** 並べ替え画面に戻るフォーム */
		$backForm = new Hlib_Form();
		$backForm->action
		= '/' . $this->getRequest()->getControllerName() . '/permute';
		$backForm->GeneralAttibutes->class = Names::BACK;
		$this->view->objBackForm = $backForm;
		/*** 並べ替え画面に戻るフォームに設置するHIDDEN */
		$hiddenReferer = new Hlib_Form_Input();
		$hiddenReferer->type = Hlib_Form_Input::TYPE_HIDDEN;
		$hiddenReferer->name = Names::REFERER;
		$hiddenReferer->value = $_REQUEST[Names::REFERER];
		$this->view->objHiddenReferer = $hiddenReferer;
		/*** カレンダーに戻るフォーム */
		$backCalendarForm = new Hlib_Form();
		$backCalendarForm->GeneralAttibutes->class = Names::CALENDARPAGEID;
		$backCalendarForm->action = $_REQUEST[Names::REFERER];
		$backCalendarForm->method = 'get';
		$this->view->objBackCalendarForm = $backCalendarForm;
	}

	/**
	 * Y地図ＵＲＬから緯度を取得する
	 * @param $urlYmap
	 * http://map.yahoo.co.jp/pl?type=scroll&lat=35.77005062785827&lon=139.91457279338354&z=16&mode=map&pointer=on&datum=wgs&fa=ks&home=on&hlat=35.77861702508&hlon=139.9030929388&layout=&ei=utf-8&p=
	 */
	static public function getLat($urlYmap)
	{
		$sResult = 	self::getQueryFromUrl($urlYmap,'lat');
		return $sResult;
	}

	/**
	 * Y地図ＵＲＬから経度を取得する
	 * @param $urlYmap
	 * http://map.yahoo.co.jp/pl?type=scroll&lat=35.77005062785827&lon=139.91457279338354&z=16&mode=map&pointer=on&datum=wgs&fa=ks&home=on&hlat=35.77861702508&hlon=139.9030929388&layout=&ei=utf-8&p=
	 */
	static public function getLon($urlYmap)
	{
		$sResult = self::getQueryFromUrl($urlYmap,'lon');
		return $sResult;
	}

	/**
	 * URLから指定queryの値を取得する
	 * @param $url
	 * @param $key
	 * @return string
	 */
	static public function getQueryFromUrl($url, $key)
	{
		$sResult = '';
		$arrQuery = array();
		$parsedUrl = parse_url($url);
		$query = $parsedUrl["query"];
		parse_str($query, $arrQuery);
		if (isset($arrQuery[$key])) {
			$sResult = $arrQuery[$key];
		}

		return $sResult;
	}
	/**
	 * 遷移元に戻る
	 */
	protected function _jumpToBack()
	{
		$urlJumpTo = $this->_makeBackUrl();
		$this->_redirect($urlJumpTo);
	}

	/**
	 * 遷移もとＵＲＬをセッションから生成する
	 */
	protected function _makeBackUrl()
	{
		$urlJumpTo = $this->_objSession->getValue('done');
		if (strpos($urlJumpTo, '?') === FALSE) {
			$urlJumpTo .= '?';
		} else {
			$urlJumpTo .= '&';
		}
		$urlJumpTo .= 'done' . '=' . Names::ADD_ASSEMBLY;
		return $urlJumpTo;
	}
}